function Rinex32Rinex2(statNameCompl,year,ConstType,OutDir,OptSaveRnx,OptName)
%Rinex32Rinex2 - RINEX3 to RINEX2 conversion (version 2.11)
%
%   Rinex32Rinex2(NameCompl,YYYY,ConstType,OutDir,OptSaveRnx,OptName)
%   Rinex32Rinex2(NameCompl,[YYYY,din,dfin],ConstType,OutDir,OptSaveRnx,OptName)
%
% This function carries out these actions for each RINEX3 file found for
% the station NameCompl (9 characters long, see below) for each day of 
% the year YYYY (for the days in the range [din,dfin] of the year YYYY if
% an input vector is considered instead of an input scalar):  
%   - download of the .gz file from the EUREF site:
%   - unzip of the .gz file, leading to a .crx file;
%   - Hatanaka's decompression of the .crx file, leading to a .rnx file;
%   - conversion RINEX3 to RINEX2, leading to a .yyo file.
% The input argument statNameCompl must be defined in accordarce with the 
% RINEX3 convention. For example, for the Italian station MEDI the complete
% name is MEDI00ITA.
% For example, for the day 123 of the year 2021 for MEDI station, whose
% RINEX3 file is 'MEDI00ITA_R_20211230000_01D_30S_GO.rnx', the output
% file is 'MEDI1230.21o', placed in the output folder OutDir. 
%
% Notes about the input arguments:
% - the input variable statNameCompl is compulsory;
% - if YYYY is undefined or empty, the current year is used (from the day
%   1 to the last day for which data are available);
% - if the second argument is a vector [YYYY,din,dfin], din and dfin are
%   intended to be defined in accordance with the yearly julian calendar;
% - ConstType is a 2 character string which defines the used constellation.
%   The possible ConstType values are:
%       'MO' (mixed), 'GO' (GPS), 'EO' (Galileo), 'RO' (GLONASS), 
%       'CO' (Beidou), 'JO' (QZSS), 'IO' (IRNSS), 'SO' (SBAS), where 
%   'O' states for observations.
%   If ConstType is undefined, empty or not admitted, ConstType = 'MO' is 
%   used. 
% - if OutDir is undefined or empty, the current directory is used;
% - if OptSaveRnx is undefined, empty or false, each RINEX3 file is deleted
%   after the conversion. If OptSaveRnx is true, the RINEX3 files are kept
%   in the folder OutDir;
% - if OptName is undefined, empty or false, the MARKER NAME value in the 
%   output file is the short station name (MEDI in the case of MEDI00ITA).
%   In this case, a file editing is automatically carried out after the 
%   conversion to RINEX2. If OptName is true, the MARKER NAME value obtained
%   by RINEX3 -> RINEX2 conversion is used.
% 
% This function requires these external packages:
%   - RNXCMP (windows10 64 bit or Linux 64 bit placed on c:\GNSS\RNXCMP\bin
%     or /mnt/c/GNSS/RNXCMP/bin/ directory respectively. If a different 
%     version and/or a different folder should be used, the function must 
%     be edited accordingly).
%     Download link: https://terras.gsi.go.jp/ja/crx2rnx.html
%   - GFZRNX (windows10 64 bit or Linux 64 bit placed on c:\GNSS\RGFZRNX or
%     /mnt/c/GNSS/GFZRNX/ directory respectively. If a different version 
%     and/or a different folder should be used, the function must be edited 
%     accordingly).
%     Download link: https://gnss.gfz-potsdam.de/services/gfzrnx 
%     (registration is necessary) 
%
%  See also Rinex32Rinex2single, StationNameEdit.  
%
%   Rinex32Rinex2(NameCompl,YYYY,ConstType,OutDir,OptSaveRnx,OptName)
%   Rinex32Rinex2(NameCompl,[YYYY,din,dfin],ConstType,OutDir,OptSaveRnx,OptName)

% G. Teza, 2022

if nargin < 6 || isempty(OptName)
    OptName = false;
end
if nargin < 5 || isempty(OptSaveRnx)
    OptSaveRnx = false;
end
if nargin < 4 || isempty(OutDir)
    OutDir = pwd;
end
if nargin < 3 || isempty(ConstType)
    ConstType = 'MO';
end
if ~ismember(ConstType,{'MO','GO','EO','RO','CO','JO','IO','SO'})
    ConstType = 'MO';
end
if nargin < 2 || isempty(year)
    vecNow = datevec(now);
    year = vecNow(1);
end

constUrl = 'http://www.epncb.oma.be/ftp/obs/';
if ispc
    commHata = '"c:\GNSS\RNXCMP\bin\crx2rnx.exe" ';
    commConv = '"c:\GNSS\GFZRNX\gfzrnx_1.16-8154_win10_64.exe" ';
elseif isunix
    commHata = '/mnt/c/GNSS/RNXCMP/bin/crx2rnx ';
    commConv = '/mnt/c/GNSS/GFZRNX/gfzrnx_1.16-8154_lx64 ';  
else
    error('Unsuitable operating system');
end

if numel(year) == 3
    din = floor(year(2));
    dfin = ceil(year(3));
    year = year(1);
else
    din = [];
end
    
years = num2str(year);
if leapy(year)
    ld = 366;
else
    ld = 365;
end
statNameCompl = upper(statNameCompl);

if isempty(din)
    din = 1;
    dfin = ld;
else
    if din > dfin
        dint = dfin;    % temporary value
        dfin = din;
        din = dint;
    end
    if din < 1
        din = 1;
    end
    if dfin > ld
        dfin = ld;
    end
end

for k = din:dfin
    dayks = sprintf('%03d',k);
    %
    % Rinex3 filenames management (WF: with folder path)
    filena3kp = [statNameCompl '_R_' years dayks '0000_01D_30S_' ConstType];
    filena3kcrx = [filena3kp '.crx'];
    filenaWF3kcrx = fullfile(OutDir,filena3kcrx);
    filena3kgz = [filena3kcrx '.gz'];
    filenaWF3kgz = fullfile(OutDir,filena3kgz);
    filena3krnx = [filena3kp '.rnx'];
    filenaWF3krnx = fullfile(OutDir,filena3krnx);
    %
    % Rinex2 filenames management: 
    filena2k = [statNameCompl(1:4)  dayks '0.' years(3:4) 'o'];
    filenaWF2k = fullfile(OutDir,filena2k);
    %
    % Download, decompression (gunzip & Hatanaka)
    fprintf('day %d - file RINEX3 download in progress...\n',k);
    complUrlk = [constUrl years '/' dayks '/' filena3kgz];
    try
        websave(filenaWF3kgz,complUrlk);
        iok = true;
    catch
        iok = false;
    end
    if ~iok
        fprintf('day %d - unsuccessful download...\n',k);
        continue
    end
    gunzip(filenaWF3kgz);
    delete(filenaWF3kgz);
    %
    % Hatanaka decompression:
    commHatak = [commHata filenaWF3kcrx];
    if exist(filenaWF3krnx,'file') % removal of the already decompressed file, if existing
        delete(filenaWF3krnx);
    end
    system(commHatak);  
    delete(filenaWF3kcrx);  % removal of the Hatanaka compressed file
    fprintf('day %d - download completed, conversion RINEX3 -> RINEX2 in progress...\n',k);
    %
    % Final conversion:
    if exist(filenaWF2k,'file')
        delete(filenaWF2k); % to remove the .d file if it already exists
    end
    commConvk = [commConv ' -finp ' filenaWF3krnx ' -fout ' filenaWF2k ' -vo 2'];
    [iexek,~] = system(commConvk);
    if ~OptName     % to solve the MARKER NAME problem, if required
        StationNameEdit(filenaWF2k);    
    end
    if iexek == 0
        fprintf('day %d - conversion completed\n',k);
    else
        fprintf('day %d - unsuccessful conversion\n',k);
    end
    % Optional RINEX3 file removal
    if ~OptSaveRnx 
        delete(filenaWF3krnx);
    end
end